
import os
import sys
import numpy as np
import collections
from time import sleep

import picamera
from mic_array import MicArray
from pixel_ring import pixel_ring
from snowboy import snowboydetect
import gpiozero
import RPi.GPIO as GPIO

import itchat

itchat.auto_login(enableCmdQR=True, hotReload=True)


pin = 12

# GPIO.setmode(GPIO.BOARD)
GPIO.setup(pin, GPIO.OUT)
pwm = GPIO.PWM(pin, 50)

pwm.start(0)

en = gpiozero.LED(5)
en.on()

pixel_ring.change_pattern('echo')

RATE = 16000
CHANNELS = 4
KWS_FRAMES = 10     # ms
DOA_FRAMES = 800    # ms

resource_path = os.path.join(os.path.dirname(snowboydetect.__file__), 'resources')
common_resource = os.path.join(resource_path, 'common.res')
model = os.path.join(resource_path, '{}.umdl'.format('snowboy'))

detector = snowboydetect.SnowboyDetect(common_resource, model)
detector.SetAudioGain(1)
detector.SetSensitivity('0.7')


camera = picamera.PiCamera()


def set_angle(angle):
    duty = angle / 18 + 2
    GPIO.output(pin, True)
    pwm.ChangeDutyCycle(duty)
    sleep(1)
    GPIO.output(pin, False)
    pwm.ChangeDutyCycle(0)


def main():
    history = collections.deque(maxlen=int(DOA_FRAMES / KWS_FRAMES))

    try:
        with MicArray(RATE, CHANNELS, RATE * KWS_FRAMES / 1000)  as mic:
            for chunk in mic.read_chunks():
                history.append(chunk)

                # Detect keyword from channel 0
                ans = detector.RunDetection(chunk[0::CHANNELS].tostring())
                if ans > 0:
                    frames = np.concatenate(history)
                    direction = mic.get_direction(frames)
                    pixel_ring.wakeup(direction)
                    print('\n{}'.format(int(direction)))

                    set_angle(direction / 3 + 30)


                    camera.start_preview()

                    sleep(3)

                    camera.capture('image.jpg')

                    itchat.send_image('image.jpg', toUserName='filehelper')

                    camera.stop_preview()


    except KeyboardInterrupt:
        pass

    pixel_ring.off()


if __name__ == '__main__':
    main()
